
#include "TSStagePlayLayerGamePrepare.h"
#include "AWorld.h"
#include "AStage.h"
#include "AString.h"
#include "TSSpritePlayer.h"
#include "TSSpriteFish.h"
#include "TSSpriteCommon.h"
#include "TSSpriteButton.h"
#include "TSSpriteBubble.h"

TSStagePlayLayerGamePrepare::TSStagePlayLayerGamePrepare(CAStage* pstage, CAStageLayer* playerParent) : CAStageLayer(pstage, playerParent)
{
	_Trace("%s allocated", __FUNCTION__);
	_NullGetters();
}

TSStagePlayLayerGamePrepare::~TSStagePlayLayerGamePrepare(void)
{
	_Trace("%s destroyed", __FUNCTION__);
}

string TSStagePlayLayerGamePrepare::debuglog() 
{ 
	char sz[256];
	sprintf(sz, "sprs=%d, state=%s", this->_getNamedSpritesCount(), 
		this->getCurrentState()->getLeafState()->getFullName().c_str());
	return sz;
}

bool TSStagePlayLayerGamePrepare::checkCondition(CAState* from, const CATransition& trans)
{
	//root.idle:	inner condition
	//root.running:	button event
	if (CAMachine::checkCondition(from, trans))
		return true;

	string fname = from->getFullName();
	if (CAString::startWith(fname, "root.fade"))
	{
		const char* pszPose = "fadein";
		if (fname == "root.fadein")
		{
		}
		else if (fname == "root.fadeout")
		{
			pszPose = "fadeout";
		}
		else
		{
			_Assert(false);
		}
		bool result = false;
		float timeout = trans.timeout;
		if (timeout > 0 && this->getTimeNow() - from->getTimeEnter() > timeout)
		{
			result = true;
		}
		else
		{
			//check 3 controls pose
			CASprite* psprs[] = 
			{
				_label_title(),
				_button_play(),
				_button_shop(),
				null,
			};
			result = _checkSpritePoseFinished(pszPose, psprs);
		}
		return result;
	}

	if (CAMachine::checkCondition(from, trans))
		return true;

	return false;
}


void TSStagePlayLayerGamePrepare::_findNumberSprites(const char* prefix, CASprite** ppsprs, int size)
{
	int i, len = strlen(prefix);
	int count = _getNamedSpritesCount(prefix);
	_Assert(count == size);

	for (i = 0; i < count; i++)
	{
		CASprite* pspr = _getNamedSprite(prefix, i);
		string gname = pspr->getGroupName();
		char c = gname[gname.length() - 1];
		_Assert(c >= '0' && c <= '9');
		int index = c - '0';
		_Assert (index >= 0 && index < size);
		{
			ppsprs[index] = pspr;
		}
	}
}

void TSStagePlayLayerGamePrepare::onStateBegin(CAState* from, void* param) 
{
	const string& fname = from->getFullName();
	if (0) ;
	else if (CAString::startWith(fname, "root.idle"))		//_onStateBeginIdle(from);
	{
		_NullGetters();
		this->removeAllTimelines();
	}
	else if (CAString::startWith(fname, "root.create"))		//_onStateBeginFadein(from);
	{
		//_pstage->resetTimer();
		_pstage->setOffset(ccp(0, 0), 0.0f);
		this->activeAllTimelines();
	}
	else if (CAString::startWith(fname, "root.fadein"))		//_onStateBeginFadein(from);
	{
		_InitGetters();

		const char* cm = "0123456789mc+";
		
#define NUMBER_COUNT 7
		CASprite* psprs[NUMBER_COUNT];
		_findNumberSprites("dist_last", psprs, NUMBER_COUNT);
		_dist_last.init(this, psprs, NUMBER_COUNT, cm);
		_findNumberSprites("dist_max", psprs, NUMBER_COUNT);
		_dist_max.init(this, psprs, NUMBER_COUNT, cm);
		_findNumberSprites("coin_last", psprs, NUMBER_COUNT);
		_coin_last.init(this, psprs, NUMBER_COUNT, cm);
		_findNumberSprites("coin_max", psprs, NUMBER_COUNT);
		_coin_max.init(this, psprs, NUMBER_COUNT, cm);

		CASprite* psprsStatic[] = 
		{
			_label_title(),
			_info_dist_last_back(),
			_info_dist_max_back(),
			_label_dist_last(),
			_label_dist_max(),
			_label_coin_last(),
			_label_coin_max(),
			null,
		};
		CASprite* psprsControls[] =
		{
			_button_play(),
			_button_shop(),
			null,
		};
		_setSpritesState(STATE_Fadein, psprsStatic);
		_setSpritesState(STATE_Fadein, psprsControls);
		_button_music()->setState(stage()->isMusicMute() ? "off_fadein" : "on_fadein");
		_button_sound()->setState(stage()->isSoundMute() ? "off_fadein" : "on_fadein");
	}
	else if (CAString::startWith(fname, "root.running"))	//_onStateBeginRunning(from);
	{
	}
	else if (CAString::startWith(fname, "root.onshop"))		//_onStateBeginOnShop(from);
	{
		//_Assert(this->_playerParent);
		//this->_playerParent->onEvent(new CAEventCommand(this, "onShop"));
	}
	else if (CAString::startWith(fname, "root.onplay"))		//_onStateBeginOnPlay(from);
	{
		_Assert(this->_playerParent);
		this->_playerParent->onEvent(new CAEventCommand(this, "onPlay"));
	}
	else if (CAString::startWith(fname, "root.fadeout"))	//_onStateBeginFadeout(from);
	{
		CASprite* psprsStatic[] = 
		{
			_label_title(),
			_info_dist_last_back(),
			_info_dist_max_back(),
			_label_dist_last(),
			_label_dist_max(),
			_label_coin_last(),
			_label_coin_max(),
			null,
		};
		CASprite* psprsControls[] =
		{
			_button_play(),
			_button_shop(),
			null,
		};
		_setSpritesState(STATE_Fadeout, psprsStatic);
		_setSpritesState(STATE_Fadeout, psprsControls);
		_button_music()->setState(stage()->isMusicMute() ? "off_fadeout" : "on_fadeout");
		_button_sound()->setState(stage()->isSoundMute() ? "off_fadeout" : "on_fadeout");

		_dist_last.setState(STATE_Fadeout);
		_dist_max.setState(STATE_Fadeout);
		_coin_last.setState(STATE_Fadeout);
		_coin_max.setState(STATE_Fadeout);
	}
	else ;
};

void TSStagePlayLayerGamePrepare::onStateEnd(CAState* from, void* param) 
{
	const string& fname = from->getFullName();
	if (0) ;
	else if (CAString::startWith(fname, "root.idle"))		//_onStateEndIdle(from);
	{
	}
	else if (CAString::startWith(fname, "root.create"))		//_onStateEndFadein(from);
	{
	}
	else if (CAString::startWith(fname, "root.fadein"))		//_onStateEndFadein(from);
	{
		_button_music()->setState(stage()->isMusicMute() ? "off" : "on");
		_button_sound()->setState(stage()->isSoundMute() ? "off" : "on");
	}
	else if (CAString::startWith(fname, "root.running"))	//_onStateEndRunning(from);
	{
	}
	else if (CAString::startWith(fname, "root.onshop"))		//_onStateEndOnShop(from);
	{
	}
	else if (CAString::startWith(fname, "root.onplay"))		//_onStateEndOnPlay(from);
	{
	}
	else if (CAString::startWith(fname, "root.fadeout"))	//_onStateEndFadeout(from);
	{
	}
	else ;
};

void TSStagePlayLayerGamePrepare::show(bool s)
{
	if (s)
	{
		this->navigateToState(getTimeNow(), this->getCurrentState(), "root.idle");
		this->setConditionResult("root.idle@user.show", true);
	}
	else
	{
		this->navigateToState(getTimeNow(), this->getCurrentState(), "root.fadeout");
	}
}

void TSStagePlayLayerGamePrepare::onEnter()
{
	GUARD_FUNCTION();

    //CCLabelTTF::labelWithString("Crazy Amber", "Arial", 16);

	CAStageLayer::onEnter();
}

static int _goNear(int cur, int to, int range, int step)
{
	if (cur == to) return cur;
	if ((cur - to < 0 && to - cur > (range >> 1)) ||
		(cur - to > 0 && cur - to < (range >> 1)))
	{
		cur += range - step;
	}
	else
	{
		cur += step;
	}
	cur %= range;

	return cur;
}

void TSStagePlayLayerGamePrepare::onUpdate() 
{
	CAStageLayer::onUpdate();
	if (this->getCurrentState()->getFullName() == "root.running")
	{
		char szNumber[32];
		sprintf(szNumber, "%dm", 0x1234);
		_dist_last.setText(szNumber);
		_dist_last.onUpdate();

		sprintf(szNumber, "%dm", 0x2234);
		_dist_max.setText(szNumber);
		_dist_max.onUpdate();

		sprintf(szNumber, "%dc", 0x2234);
		_coin_last.setText(szNumber);
		_coin_last.onUpdate();

		sprintf(szNumber, "%dc", 0x2234);
		_coin_max.setText(szNumber);
		_coin_max.onUpdate();

		int c = this->_getNamedSpritesCount("bubble");
		if (c < 20)
		{
			TSSpriteBubble* pspr;
			pspr = (TSSpriteBubble*)CAWorld::sharedWorld().createSprite(this, "bubble");

			CCPoint pos;
			pos.x = CAUtils::Rand() * 0.8f + 0.1f;
			pos.y = CAUtils::Rand() * 0.1f;
			pos = stage()->getPointFromPercent(pos, false);

			pspr->setPos(pos);

			float sc = CAUtils::Rand() * 0.2f + 0.1f;
			pspr->setScl(sc * 2.0f);
			//pspr->setMoveDirection(270.0f);
			//sc = CAUtils::Rand(0.5f, 1.1f);
			//pspr->setMoveSpeed(-sc * 70.0f);

			pspr->setZOrder(_label_title()->getZOrder() - CAUtils::Rand(0.0f, 0.3f));

			this->addSprite(pspr);
			pspr->switchPose("pop_slow");
		}
	}
};

void TSStagePlayLayerGamePrepare::onExit()
{
	CAStageLayer::onExit();
}

void TSStagePlayLayerGamePrepare::onEvent(CAEvent* pevt)
{
	CAStageLayer::onEvent(pevt);

	switch (pevt->type())
	{
	case ET_Touch:
		{
			CAEventTouch* ptouch = (CAEventTouch*)pevt;
			switch (ptouch->state())
			{
			case kTouchStateGrabbed:
				{
				}
				break;
			case kTouchStateUngrabbed:
				{
				}
				break;
			}
		}
		break;
	case ET_Command:
		{
			CAEventCommand* pec = (CAEventCommand*)pevt;
			if (pec->command() == "onClick")
			{
				_Assert(pec->getSenderType() == ST_Sprite);
				CASprite* pspr = (CASprite*)pec->sender();
				string name;
				name = pspr->getModName();
				if (name == "button_shop")
				{
					this->setConditionResult("root.running@user.shop", true);
				}
				else if (name == "button_play")
				{
					this->setConditionResult("root.running@user.play", true);
				}
				else if (name == "button_music")
				{
					if (stage()->isMusicMute())
					{
						stage()->enableMusic(true);
						_button_music()->setState("on");
					}
					else
					{
						stage()->enableMusic(false);
						_button_music()->setState("off");
					}
				}
				else if (name == "button_sound")
				{
					if (stage()->isSoundMute())
					{
						stage()->enableSound(true);
						_button_sound()->setState("on");
					}
					else
					{
						stage()->enableSound(false);
						_button_sound()->setState("off");
					}
				}
			}
		}
		break;
	}
}

